package com.yunxi.core.util;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xssf.usermodel.*;

import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;
import java.util.stream.Collectors;

public class ExportExcel<T> {
   public void exportExcel(String[] headers, Collection<T> data, String[] fileNames, HttpServletResponse response,String filePath) throws IllegalAccessException {
      // 声明一个工作薄
      XSSFWorkbook workbook = new XSSFWorkbook();
      // 生成一个表格
      XSSFSheet sheet = null;
      String name = null;
      for (String fileName : fileNames) {
         sheet = workbook.createSheet(fileName);
         name= fileName;
      }
      // 设置表格默认列宽度为15个字节
      sheet.setDefaultColumnWidth((short) 20);
      // 产生表格标题行
      XSSFRow row = sheet.createRow(0);

      //所有字段属性值集合
      List<String> filedValueList = new ArrayList<>(headers.length);
      for (int k = 0; k < headers.length; k++) {
         filedValueList.add(k,"");
      }

      Iterator<T> it1 = data.iterator();
      int index1 = 0;
      Field[] fields1 = null;
      while (it1.hasNext()) {
         index1++;
         T t = (T) it1.next();
         fields1 = t.getClass().getDeclaredFields();
         break;
      }

      Iterator<T> it2 = data.iterator();
      while (it2.hasNext()) {
         T t = (T) it2.next();

      for (int j = 0; j < fields1.length-1; j++) {
         Field f = fields1[j];//遍历属性
         f.setAccessible(true); // 设置属性是可以访问的(私有的也可以)
         Object val = f.get(t);// 得到此属性的值
            if(val!=null && (val+"").length()>0  ) {//只要有1个属性不为空,那么就不是所有的属性值都为空
               filedValueList.set(j,filedValueList.get(j)+ val.toString());
            }
         }
      }

      List<String> headerList = Arrays.asList(headers);
      headerList = new ArrayList<>(headerList);
      for (int i = 0; i < filedValueList.size(); i++) {
         String filedValue = filedValueList.get(i);
         if (StringUtils.isEmpty(filedValue)){
            headerList.set(i,"");
         }
      }

      headerList=headerList.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());
      String[] actualHeaders = new String[headerList.size()];
      actualHeaders = headerList.toArray(actualHeaders);


      for (short i = 0; i < actualHeaders.length; i++) {
         XSSFCell cell = row.createCell(i);
         XSSFRichTextString text = new XSSFRichTextString(actualHeaders[i]);
         cell.setCellValue(text);
      }
      try {
         // 遍历集合数据，产生数据行
         Iterator<T> it = data.iterator();
         int index = 0;
         int colNum = 0;
         while (it.hasNext()) {
            index++;
            row = sheet.createRow(index);
            T t = (T) it.next();
            // 利用反射，根据javabean属性的先后顺序，动态调用getXxx()方法得到属性值
            Field[] fields = t.getClass().getDeclaredFields();
            for (short i = 0; i < fields.length-1; i++) {
               String fieleValueStr = filedValueList.get(i);
               if (StringUtils.isNotEmpty(fieleValueStr)){
                  Field field = fields[i];
                  String fieldName = field.getName();
                  String getMethodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
                  Class tCls = t.getClass();
                  Method getMethod = tCls.getMethod(getMethodName, new Class[] {});
                  Object value = getMethod.invoke(t, new Object[] {});


                  XSSFCell cell = row.createCell(colNum);
                  // 判断值的类型后进行强制类型转换
                  String textValue = null;
                  // 其它数据类型都当作字符串简单处理
                  if(value != null && value != ""){
                     textValue = value.toString();
                  }
                  if (textValue != null) {
                     XSSFRichTextString richString = new XSSFRichTextString(textValue);
                     cell.setCellValue(richString);
                  }
                  colNum++;
               }
            }
            colNum = 0;
         }
         getExportedFile(workbook, name,response,filePath);
      } catch (Exception e) {
         e.printStackTrace();
      }
   }

   /**
    *
    * 方法说明: 指定路径下生成EXCEL文件
    * @return
    */
   public void getExportedFile(XSSFWorkbook workbook, String name,HttpServletResponse response,String filePath) throws Exception {
      BufferedOutputStream fos = null;
      try {
         String fileName = filePath+"/"+name + ".xlsx";
//			response.setContentType("application/x-msdownload");
//			response.setHeader("Content-Disposition", "attachment;filename=" + new String( name.getBytes("utf-8"),"iso-8859-1")+ ".xlsx" );
//			fos = new BufferedOutputStream(response.getOutputStream());
         FileOutputStream fileOutputStream = new FileOutputStream(fileName);
         fos = new BufferedOutputStream(fileOutputStream);
         workbook.write(fos);
      } catch (Exception e) {
         e.printStackTrace();
      } finally {
         if (fos != null) {
            fos.close();
         }
      }
   }
}